package com.atguigu.daijia.driver.service.impl;

import com.atguigu.daijia.common.execption.GuiguException;
import com.atguigu.daijia.common.result.ResultCodeEnum;
import com.atguigu.daijia.driver.config.TencentCloudProperties;
import com.atguigu.daijia.driver.service.CiService;
import com.atguigu.daijia.driver.service.CosService;
import com.atguigu.daijia.model.vo.driver.CosUploadVo;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URL;
import java.util.Date;
import java.util.UUID;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class CosServiceImpl implements CosService {

    @Autowired
    private TencentCloudProperties tencentCloudProperties;
    @Autowired
    private CiService ciService;

    @Override
    public CosUploadVo upload(MultipartFile file, String path) {
        log.info("首先获取cosClient对象");
        COSClient cosClient = getCosClient();
        log.info("4  设置 元数据信息");
        ObjectMetadata meta = new ObjectMetadata();
        meta.setContentLength(file.getSize());
        meta.setContentEncoding("UTF-8");
        meta.setContentType(file.getContentType());

        log.info("5  设置 文件的名字 和 要上传的路径");
        String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); //文件后缀名
        String uploadPath = "/driver/" + path + "/" + UUID.randomUUID().toString().replaceAll("-", "") + fileType;
        // 01.jpg
        // /driver/auth/0o98754.jpg
        PutObjectRequest putObjectRequest = null;
        try {
            log.info("6. 创建上传文件需要的请求对象，设置桶名，设置上传路径，设置文件流，设置原数据的一些基本信息用于校验数据完整性");
            putObjectRequest = new PutObjectRequest(tencentCloudProperties.getBucketPrivate(),
                    uploadPath,
                    file.getInputStream(),
                    meta);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("7. 设置cos数据类型 使用默认的");
        putObjectRequest.setStorageClass(StorageClass.Standard);
        log.info("8. 上传文件,向存储桶中保存文件");
        PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
        log.info("9. 关闭cos客户端");
        cosClient.shutdown();

        log.info("图片审核");
        Boolean imageAuditing = ciService.imageAuditing(uploadPath);
        if(!imageAuditing) {
            //删除违规图片
            cosClient.deleteObject(tencentCloudProperties.getBucketPrivate(),uploadPath);
            throw new GuiguException(ResultCodeEnum.IMAGE_AUDITION_FAIL);
        }

        log.info("10. 返回vo对象");
        CosUploadVo cosUploadVo = new CosUploadVo();
        cosUploadVo.setUrl(uploadPath);
        log.info("设置带有效时间的临时访问地址");
        cosUploadVo.setShowUrl(getShowUrl(uploadPath));
        return cosUploadVo;
    }

    /**
     * 通过上传文件的真是路径 获取到一个带 有效时间 的 临时访问的地址
     * @param path
     * @return
     */
    @Override
    public String getShowUrl(String path) {
        log.info("1. 果path为空，就直接返回");
        if(!StringUtils.hasText(path)) return "";
        log.info("2. 获取cos客户端");
        COSClient cosClient = this.getCosClient();
        log.info("3. 创建获取临时访问资源的地址的请求体");
        GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(tencentCloudProperties.getBucketPrivate(), path, HttpMethodName.GET);
        log.info("4. 设置临时访问资源地址的有效时间是15分钟");
        Date expiration = new DateTime().plusMinutes(15).toDate();  //设置过期时间是 当前时间+ 15分钟
        request.setExpiration(expiration);
        log.info("5. 发请求到腾讯云获取到临时地址");
        URL url = cosClient.generatePresignedUrl(request);
        log.info("6. 将临时地址返回前端");
        return url.toString();
    }

    private COSClient getCosClient() {
        log.info("1 初始化用户身份信息（secretId, secretKey）。");
        String secretId = tencentCloudProperties.getSecretId();
        String secretKey = tencentCloudProperties.getSecretKey();
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        log.info("2  设置 bucket 的地域, COS 地域");
        Region region = new Region(tencentCloudProperties.getRegion());
        ClientConfig clientConfig = new ClientConfig(region);
        log.info("2.1 设置使用 https 协议");
        clientConfig.setHttpProtocol(HttpProtocol.https);
        log.info("3  生成 cos 客户端。");
        return new COSClient(cred, clientConfig);
    }
}
